using System;
using System.Runtime.Serialization;
using OhioState.AssetManaged;

namespace OhioState.Graphics.Proxy
{
    /// <summary>
    /// BoxOutlineProxy Class that defines the outline for a box
    /// </summary>
    [Serializable()]
    public class BoxOutlineProxy : SharedAsset, IDrawable
    {
        #region Public Properties
        private bool _drawBackEdges = true;
        /// <summary>
        /// Get/Set Accessor to draw back edges
        /// </summary>
        public bool DrawBackEdges
        {
            get { return _drawBackEdges; }
            set
            {
                _drawBackEdges = value;
                FireUpdateChangedEvent(this);
            }
        }
        private bool _drawFrontEdges = true;
        /// <summary>
        /// Get/Set Accessor to draw front edges
        /// </summary>
        public bool DrawFrontEdges
        {
            get { return _drawFrontEdges; }
            set
            {
                _drawFrontEdges = value;
                FireUpdateChangedEvent(this);
            }
        }
        private SharedBox _box;
        /// <summary>
        /// Implementation of IDrawable Get Accessor BoundingVolume
        /// </summary>
        public IBoundingVolume BoundingVolume
        {
            get { return _box.BBox; }
        }
       
        private MaterialProxy _material;
        /// <summary>
        /// Get/Set Accessor for BoxOutline's material
        /// </summary>
        public IMaterial Material
        {
            get { return _material; }
            set
            {
                //
                // For fields that contain shared objects, follow this sequence:
                //   1. rewire the notification for the shared object
                //        this property points to.
                //   2. set the property.
                //   3. perform any internal updates.
                //   4. Implicit in step 3 would be changing this 
                //         object and hence notifying it's subscribers.
                //
                IAssetManagedHandler changedEvent = new IAssetManagedHandler(Box_ChangedEvent);
                MaterialProxy mat = value as MaterialProxy;
                if (mat != null)
                {
                    this.SetPropertyEventHandling(_material, mat, changedEvent);
                    _material = mat;
                    Box_ChangedEvent(mat);
                }
            }
        }
        #endregion Public Properties
        
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="name">name of the asset</param>
        /// <param name="box">box</param>
        public BoxOutlineProxy(String name, SharedBox box)
            : base(name)

        {
            _box = box;
            _material = MaterialProxy.White;
            IAssetManagedHandler changedEvent = new IAssetManagedHandler(Box_ChangedEvent);
            _box.AddChangedEventHandler(changedEvent);
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="box">box</param>
        public BoxOutlineProxy(SharedBox box)
            : this("BoxOutline", box)
        {
        }
        /// <summary>
        /// Get/Set Accessor for the Box
        /// </summary>
        public SharedBox Box
        {
            get { return _box; }
            set
            {
                IAssetManagedHandler changedEvent = new IAssetManagedHandler(Box_ChangedEvent);
                this.SetPropertyEventHandling(_box, value, changedEvent);
                _box = value;
                Box_ChangedEvent(_box);
            }
        }
        /// <summary>
        /// Implementation of IDrawable Render method
        /// </summary>
        /// <param name="panel"></param>
        public virtual void Render(IRenderPanel panel)
        {
        }
        
        private void Box_ChangedEvent(IAssetManaged obj)
        {
            FireUpdateChangedEvent(this);
        }
        /// <summary>
        /// Overrides shared object ToString method
        /// </summary>
        /// <returns>A string representing parent shared object name</returns>
        public override String ToString()
        {
            return base.Name;
        }
        /// <summary>
        /// Implementation of SharedAsset method ReaquireAssets
        /// </summary>
        public override void ReaquireAssets()
        {
            //
            // Use the Properties to ensure the old event handlers are removed and new
            //    ones are added. Particularly if we are setting an item to itself.
            //
            IAssetManaged item = AssetManager.Instance.Find(_box.GetType(), _box.Name);
            if (item != _box)
            {
                this.Box = item as SharedBox;
            }
            item = AssetManager.Instance.Find(_material.GetType(), _material.Name);
            if (item != _material)
            {
                this.Material = item as IMaterial;
            }
        }
        [OnDeserialized]
        private void OnDeserialized(StreamingContext context)
        {
            IAssetManagedHandler changedEvent = new IAssetManagedHandler(Box_ChangedEvent);
            _box.AddChangedEventHandler(changedEvent);
            _material.AddChangedEventHandler(changedEvent);
        }
    }
}
